﻿Option Compare Text

Public Class FrmMain

    Dim File As String = ""
    Dim Modified As Boolean = False
    Dim SaveDialog As New SaveFileDialog
    Dim OpenDialog As New OpenFileDialog
    Dim FontSize As Single = 9

    Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByRef lParam As IntPtr) As Integer
    Const EM_SETTABSTOPS = &HCB

    Sub New()
        InitializeComponent()
        ToolStripContainer1.TopToolStripPanel.Renderer = New FirefoxRenderer
        ToolStrip1.Renderer = New FirefoxRenderer
        MenuStrip1.Renderer = New FirefoxRenderer
        MnuNew.Image = BtnNew.Image
        MnuOpen.Image = BtnOpen.Image
        MnuSave.Image = BtnSave.Image
        MnuPrint.Image = BtnPrint.Image
        MnuCut.Image = BtnCut.Image
        MnuCopy.Image = BtnCopy.Image
        MnuPaste.Image = BtnPaste.Image
        'SendMessage(TextBox.Handle, EM_SETTABSTOPS, 1, 12)
        Tree.LabelEdit = True
        Tree.ImageSize = New Size(16, 16)
        Tree.ImageLeaf = My.Resources.document
        Tree.ImageFolder = My.Resources.folder
        Tree.AutoImage = True
        StartupBar.Renderer = New TransparentRenderer
        BtnSNew.Image = BtnNew.Image
        BtnSOpen.Image = BtnOpen.Image
    End Sub

    Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If keyData = (Keys.Down Or Keys.Control) Then
            MnuMoveDown.PerformClick()
            Return True
        ElseIf keyData = (Keys.Up Or Keys.Control) Then
            MnuMoveUp.PerformClick()
            Return True
        End If
        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function

    Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean
        If keyData = (Keys.Control Or Keys.Return) Then
            MnuInsertBefore.PerformClick()
            Return True
        ElseIf keyData = (Keys.Shift Or Keys.Return) Then
            MnuInsertSubnode.PerformClick()
            Return True
        ElseIf keyData = Keys.Return Then
            MnuInsertAfter.PerformClick()
            Return True
        ElseIf keyData = (Keys.Tab Or Keys.Shift) Then
            MnuMoveLeft.PerformClick()
            Return True
        ElseIf keyData = Keys.Tab Then
            MnuMoveRight.PerformClick()
            Return True
        ElseIf keyData = Keys.Back AndAlso Not Tree.SelectedNode.IsEditing Then
            MnuMoveLeft.PerformClick()
            Return True
        ElseIf keyData = Keys.F2 Then
            Tree.SelectedNode.BeginEdit()
        ElseIf keyData = Keys.Delete AndAlso Not Tree.SelectedNode.IsEditing Then
            MnuDelete.PerformClick()
        End If
        Return MyBase.ProcessDialogKey(keyData)
    End Function

    Private Sub MnuSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuSave.Click, BtnSave.Click
        If File = "" Then MnuSaveAs.PerformClick() : Exit Sub
        Dim Contents = SaveNode(Tree.Nodes)
        My.Computer.FileSystem.WriteAllText(File, Contents, False)
        Dim CompressedFile = IO.File.Create(File & ".zip")
        Dim Zipper As New IO.Compression.GZipStream(CompressedFile, IO.Compression.CompressionMode.Compress)
        Zipper.Write((New System.Text.UTF8Encoding).GetBytes(Contents), 0, Contents.Length)
        Zipper.Close()
        AddRecent(File)
        Modified = False
    End Sub

    Sub Open()
        Dim Data = My.Computer.FileSystem.ReadAllText(File, System.Text.Encoding.Default)
        Dim Parent As TreeNode = Nothing
        AddRecent(File)
        Tree.Nodes.Clear()
        Panel1.Visible = False
        Tree.Visible = True
        Tree.Focus()
        Dim Indent As Integer = 0
        For Each Line In Split(Data, vbCrLf).Where(Function(x) x <> "")
            Dim NewIndent = Line.Length - Line.Replace(vbTab, "").Length
            If NewIndent = Indent + 1 Then
                Parent = If(Parent Is Nothing, Tree.Nodes, Parent.Nodes).Last
            Else
                For i = NewIndent + 1 To Indent
                    Parent = Parent.Parent
                Next
            End If
            Dim Node = Tree.Add(Parent, Line.Replace(vbTab, ""))
            Node.ForeColor = Choose(Node.Level, Color.Red, Color.Blue, Color.Gray, Color.DarkGreen)
            Indent = NewIndent
        Next
        Text = File & " - TreeEdit"
        Modified = False
    End Sub

    Function SaveNode(ByVal Nodes As TreeNodes) As String
        Dim Text As String = ""
        For Each Node As TreeNode In Nodes
            Text &= Strings.StrDup(Node.Level, vbTab) & Node.Text & vbCrLf & SaveNode(Node.Nodes)
        Next
        Return Text
    End Function

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        e.Cancel = Not CheckSaved()
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ReadRecent()
    End Sub

    Private Sub MnuInsertBefore_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuInsertBefore.Click
        Tree.SelectedNode = Tree.InsertBefore(Tree.SelectedNode, "")
        Tree.SelectedNode.BeginEdit()
        Modified = True
    End Sub

    Private Sub MnuInsertAfter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuInsertAfter.Click
        Tree.SelectedNode = Tree.InsertAfter(Tree.SelectedNode, "")
        Tree.SelectedNode.BeginEdit()
        Modified = True
    End Sub

    Private Sub MnuInsertSubnode_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuInsertSubnode.Click
        Tree.SelectedNode = Tree.Add(Tree.SelectedNode, "")
        Tree.SelectedNode.BeginEdit()
        Modified = True
    End Sub

    Private Sub MnuMoveRight_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuMoveRight.Click
        If Tree.SelectedNode.PrevNode Is Nothing Then Exit Sub
        Dim InEditMode = Tree.SelectedNode.IsEditing
        Dim Node = Tree.SelectedNode
        Dim Prev = Tree.SelectedNode.PrevNode
        Node.Parent = Prev
        Tree.SelectedNode = Node
        If InEditMode Then Node.BeginEdit()
        Modified = True
    End Sub

    Private Sub MnuMoveLeft_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuMoveLeft.Click
        If Tree.SelectedNode.Parent Is Nothing Then Exit Sub
        Dim InEditMode = Tree.SelectedNode.IsEditing
        Dim Node = Tree.SelectedNode
        Dim Prev = Tree.SelectedNode.Parent
        Node.Remove()
        Prev.Parent.Nodes.Insert(Prev.Index + 1, Node)
        Tree.SelectedNode = Node
        If InEditMode Then Node.BeginEdit()
        Modified = True
    End Sub

    Private Sub MnuNodeEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuNodeEdit.Click
        Tree.SelectedNode.BeginEdit()
    End Sub

    Private Sub MnuMoveDown_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuMoveDown.Click
        Dim Node = Tree.SelectedNode
        Node.MoveDown()
        Node.Select()
        Modified = True
    End Sub

    Private Sub MnuMoveUp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuMoveUp.Click
        Dim Node = Tree.SelectedNode
        Node.MoveUp()
        Node.Select()
        Modified = True
    End Sub

    Private Sub MnuSaveAs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuSaveAs.Click
        SaveDialog.FileName = File
        SaveDialog.DefaultExt = "txt"
        SaveDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"
        If SaveDialog.ShowDialog <> Windows.Forms.DialogResult.OK Then Exit Sub
        File = SaveDialog.FileName
        Text = File & " - TreeEdit"
        MnuSave.PerformClick()
    End Sub

    Private Sub MnuNew_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MnuNew.Click, BtnNew.Click, BtnSNew.Click
        If Not CheckSaved() Then Exit Sub
        Tree.Nodes.Clear()
        Panel1.Visible = False
        Tree.Visible = True
        Tree.Focus()
        File = ""
        Text = "New File - TreeEdit"
        Modified = False
    End Sub

    Function CheckSaved() As Boolean
        If Not Modified Then Return True
        Select Case MsgBox("Değişiklikleri kaydetmek istiyor musunuz?", vbYesNoCancel + MsgBoxStyle.Question, "Onay")
            Case vbYes
                MnuSave.PerformClick()
            Case vbNo
                Modified = False
        End Select
        Return Not Modified
    End Function

    Private Sub MnuViewText_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        'TextBox.Text = SaveNode(Tree.Nodes)
        'TextBox.Visible = True
        Tree.Visible = False
        'TextBox.Focus()
    End Sub

    Private Sub MnuOpen_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MnuOpen.Click, BtnOpen.Click, BtnSOpen.Click
        If Not CheckSaved() Then Exit Sub
        OpenDialog.DefaultExt = "txt"
        OpenDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"
        If OpenDialog.ShowDialog <> Windows.Forms.DialogResult.OK Then Exit Sub
        File = OpenDialog.FileName
        Text = File & " - TreeEdit"
        Open()
    End Sub

    Dim RecentFiles As New List(Of String)

    Private Sub AddRecent(ByVal File As String)
        If RecentFiles.Contains(File) Then RecentFiles.Remove(File)
        RecentFiles.Insert(0, File)
        SaveSetting("TreeNote", "Files", "Recent", Join(RecentFiles.ToArray, "|"))
        ReadRecent()
    End Sub

    Private Sub ReadRecent()
        Dim Files As String = GetSetting("TreeNote", "Files", "Recent", "")
        If Files = "" Then Exit Sub
        RecentFiles = Files.Split("|").ToList
        MnuRecent.DropDownItems.Clear()
        For Each Item In (From b In StartupBar.Items Where b.Tag <> "").ToList
            StartupBar.Items.Remove(Item)
        Next
        For Each File As String In RecentFiles
            MnuRecent.DropDownItems.Add(File, MnuNew.Image)
            Dim Button = StartupBar.Items.Add(File)
            Button.Tag = File
            Button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText
            Button.Image = BtnNew.Image
        Next
    End Sub

    Private Sub MnuRecent_DropDownItemClicked(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles MnuRecent.DropDownItemClicked
        If Not CheckSaved() Then Exit Sub
        File = e.ClickedItem.Text
        Open()
    End Sub

    Private Sub Tree_AfterLabelEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.NodeLabelEditEventArgs) Handles Tree.AfterLabelEdit
        If e.Label Is Nothing Then Exit Sub
        Modified = e.Label <> Tree.SelectedNode.Text
    End Sub

    Private Sub MnuDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuDelete.Click
        If MsgBox("Seçilen bölümü silmek istediğinizden emin misiniz?", vbOKCancel + MsgBoxStyle.Question, "Onay") <> MsgBoxResult.Ok Then Exit Sub
        Tree.SelectedNode.Remove()
    End Sub

    Private Sub MnuExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuExit.Click
        Close()
    End Sub

    Private Sub MnuClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuClose.Click
        If Not CheckSaved() Then Exit Sub
        Panel1.Visible = True
        Tree.Visible = False
    End Sub

    Private Sub Tree_MouseWheel(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Tree.MouseWheel
        If Control.ModifierKeys = Keys.Control Then
            FontSize *= If(e.Delta > 0, 1.1, 0.9)
            If FontSize < 3 Then FontSize = 3
            If FontSize > 31 Then FontSize = 31
            Tree.Font = New Font(Tree.Font.Name, FontSize, Tree.Font.Style)
        End If
    End Sub

    Private Sub MnuExpandAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuExpandAll.Click
        Tree.BeginUpdate()
        Tree.ExpandAll()
        Tree.EndUpdate()
    End Sub

    Private Sub MnuCollapseAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuCollapseAll.Click
        Tree.CollapseAll()
    End Sub

    Private Sub MnuBold_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuBold.Click
        If Not Tree.Font.Bold Then
            Tree.Font = New Font(Tree.Font, Tree.Font.Style + FontStyle.Bold)
        Else
            Tree.Font = New Font(Tree.Font, Tree.Font.Style - FontStyle.Bold)
        End If
    End Sub

    Private Sub MnuCut_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuCut.Click, BtnCut.Click
        Tree.Cut()
    End Sub

    Private Sub MnuCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuCopy.Click, BtnCopy.Click
        Tree.Copy()
    End Sub

    Private Sub MnuPaste_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuPaste.Click, BtnPaste.Click
        Tree.Paste()
    End Sub

    Private Sub MnuSelectAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuSelectAll.Click
        Tree.SelectAll()
    End Sub

    Private Sub TreeRecent_NodeMouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs)
        File = e.Node.Text
        Open()
    End Sub

    Private Sub StartupBar_ItemClicked(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles StartupBar.ItemClicked
        If e.ClickedItem.Tag <> "" Then
            File = e.ClickedItem.Tag
            Open()
        End If
    End Sub

    Private Sub MnuFind_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuFind.Click
        Dim Form As New FrmFind With {.Caller = Me, .Info = FindParams}
        Form.ShowDialog()
    End Sub

    Dim FindParams As New FindInfo

    Class FindInfo
        Public Text As String
        Public Type As Integer
        Public SearchNode As TreeNode
        Public LastNode As TreeNode
    End Class

    Private Sub MnuFindNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuFindNext.Click
        If FindParams.Text = "" Then
            MnuFind.PerformClick()
            Exit Sub
        End If
        Do
            If FindParams.LastNode Is Nothing Then
                FindParams.LastNode = Tree.Nodes.First
            ElseIf FindParams.LastNode.Nodes.Count > 0 Then
                FindParams.LastNode = FindParams.LastNode.Nodes.First
            ElseIf Not FindParams.LastNode.NextNode Is Nothing Then
                FindParams.LastNode = FindParams.LastNode.NextNode
            Else
                Do
                    FindParams.LastNode = FindParams.LastNode.Parent
                    If FindParams.LastNode Is FindParams.SearchNode Then
                        MsgBox("No more matches found.", MsgBoxStyle.Information)
                        Exit Sub
                    End If
                    If Not FindParams.LastNode.NextNode Is Nothing Then
                        FindParams.LastNode = FindParams.LastNode.NextNode
                        Exit Do
                    End If
                Loop
            End If
            If FindParams.LastNode.Text Like "*" & FindParams.Text & "*" Then
                FindParams.LastNode.Select()
                Exit Do
            End If
        Loop
    End Sub

    Private Sub MnuTreelines_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuTreelines.Click
        Tree.ShowLines = Not Tree.ShowLines
    End Sub

    Private Sub MnuIndentInc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuIndentInc.Click
        Tree.Indentation += 1
    End Sub

    Private Sub MnuIndentDec_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuIndentDec.Click
        Tree.Indentation -= 1
    End Sub

    Private Sub MnuSort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MnuSort.Click
        Tree.SelectedNode.Sort()
        Modified = True
    End Sub

End Class

Class TransparentRenderer : Inherits ToolStripProfessionalRenderer

    Protected Overrides Sub OnRenderToolStripBackground(ByVal e As System.Windows.Forms.ToolStripRenderEventArgs)
    End Sub

    Protected Overrides Sub OnRenderSeparator(ByVal e As System.Windows.Forms.ToolStripSeparatorRenderEventArgs)
    End Sub

    Protected Overrides Sub OnRenderToolStripBorder(ByVal e As System.Windows.Forms.ToolStripRenderEventArgs)
    End Sub

End Class